package message;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import comunity.Community;
import comunity.Status;
import comunity.UserInfo;

public class Registration extends Packet {
	String username;
	String password;
	
	private static final String USERNAME_ATTRIBUTE = "username";
	private static final String PASSWORD_ATTRIBUTE = "password";
	public static final int INVALID_USERNAME = 1;
	

	public Registration(String username, String password, int port, double lat, double lon) {
		super(PacketType.REGISTRATION, port, lat, lon);
		this.username = username;
		this.password = password;
	}
	
	@Override
	public String toXML() {
		Document doc = null;
		try {
			doc = super.createXMLDocument();
		} catch (ParserConfigurationException e1) {
			e1.printStackTrace();
		}
		
	    Element root = doc.createElement(rootElementTag());
	    doc.appendChild(root);
	    root.setAttribute(USERNAME_ATTRIBUTE, username);
	    root.setAttribute(PASSWORD_ATTRIBUTE, password);
	    
	    Element connectionElement = super.createConnectionElement(doc);
	    root.appendChild(connectionElement);
	    
	    String result = null;
	    try {
			result = super.generateString(doc);
		} catch (TransformerFactoryConfigurationError | TransformerException e) {
			e.printStackTrace();
		}
	    return result;
	}

	@Override
	String rootElementTag() {
		return PacketType.REGISTRATION.toString();
	}
	
	public static Registration createRegistration(String xmlString){
		Document doc = Packet.createXMLDocumentFromString(xmlString);

		NodeList list = doc.getElementsByTagName(PacketType.REGISTRATION.toString());
		Node rootNode = list.item(0);
		Node connectionNode = rootNode.getFirstChild();

		NamedNodeMap rootAttributes = rootNode.getAttributes();
		NamedNodeMap connectionAttributes = connectionNode.getAttributes();
		
		return new Registration(
				rootAttributes.getNamedItem(USERNAME_ATTRIBUTE).getNodeValue(),
				rootAttributes.getNamedItem(PASSWORD_ATTRIBUTE).getNodeValue(),
				Integer.parseInt(connectionAttributes.getNamedItem(Packet.PORT_ATTRIBUTE).getNodeValue()),
				Double.parseDouble(connectionAttributes.getNamedItem(Packet.LAT_ATTRIBUTE).getNodeValue()),
				Double.parseDouble(connectionAttributes.getNamedItem(Packet.LON_ATTRIBUTE).getNodeValue())
				);
	}
	
	public String getPassword() {
		return password;
	}
	
	public String getUsername() {
		return username;
	}
	
	@Override
	public String getReceiver() {
		return this.getUsername();
	}

	@Override
	public int handlePacket(String address) {
		Community community = Community.obtainCommunity();
		UserInfo userInfo = new UserInfo(Status.ONLINE,
				this.getUsername(), this.getPassword(),
				/*address, this.getPort(),*/ this.getLat(),
				this.getLon());
		userInfo.setNewUser(true);

		if (community.contains(userInfo)
				|| this.getUsername().equalsIgnoreCase(
						Community.broadcastWildcard))
			return Registration.INVALID_USERNAME;

		community.addUserInfo(userInfo);
		community.setUserGPSLocation(this.getUsername(), this.getLat(), this.getLon());

		return Packet.OK;
	}

}
